home *** CD-ROM | disk | FTP | other *** search
- /*-------------------------------------------------------------------------------------
- *
- * Simple Sample AOCE Application Framework
- *
- * ©1991-1993 Apple Computer
- *
- -------------------------------------------------------------------------------------*/
- /*
- * digisig.c -- digital signature stuff
- *
- * change history:
- *
- * SJF 03/08/93 1.0b1 initial coding
- *
- */
-
- #ifndef __TYPES__
- #include <Types.h>
- #endif
-
- #ifndef __FOLDERS__
- #include <Folders.h>
- #endif
-
- #ifndef __FILES__
- #include <Files.h>
- #endif
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifndef __DIGITALSIGNATURE__
- #include <DigitalSignature.h>
- #endif
-
- #include "const.h"
- #include "mytypes.h"
- #include "globals.h"
- #include "utils.h"
- #include "windowstuff.h"
- #include "strconst.h"
- #include "mymenus.h"
- #include "draw.window.h"
- #include "IconSuites.h"
-
- #include "digisig.h"
-
-
- #define kDSIGPattern 7
- #define kDSIGFrameSize 2
-
- // static globals
-
- static short gDSTempRefNum;
- static FSSpec gDSTempFSpec;
-
- // routines
-
- OSErr InitDigitalSignatures(void)
- {
- OSErr err;
-
- gShowSigners = false;
-
- err = FindFolder(kOnSystemDisk,kTemporaryFolderType,true,&gDSTempFSpec.vRefNum,&gDSTempFSpec.parID);
- if (err!=noErr)
- return err;
- GetResString((StringPtr)&gDSTempFSpec.name,kTempDSFileID,kTempDSFile);
-
- FSpCreateResFile(&gDSTempFSpec,kAppCreator,'????',smRoman);
- if (ResError()==dupFNErr) {
- FSpDelete(&gDSTempFSpec);
- FSpCreateResFile(&gDSTempFSpec,kAppCreator,'????',smRoman);
- }
- if (ResError()==noErr)
- gDSTempRefNum = FSpOpenResFile(&gDSTempFSpec,fsRdWrPerm);
-
- return ResError();
- }
-
-
- void ExitDigitalSignatures(void)
- {
- CloseResFile(gDSTempRefNum);
- FSpDelete(&gDSTempFSpec);
- }
-
-
- void DSIGSetupSignMenu(WindowPtr window,WInfoPtr infoPtr)
- {
- MenuHandle theMenu;
- ShapeListPtr shapeList;
- Boolean gotSigned;
-
- theMenu = GetMHandle(kSignMenu);
-
- if (!gHasAOCE) {
- DisableItem(theMenu,0);
- return;
- }
-
- EnableAllMenuItems(theMenu);
-
- if (!CheckShapeSelected(window,infoPtr))
- DisableItem(theMenu,kSignItem);
-
- gotSigned = false;
- for (shapeList=infoPtr->data; shapeList!=nil; shapeList=shapeList->next) {
- if ((shapeList->isSigned) && (shapeList->selected))
- gotSigned = true;
- }
- if (!gotSigned)
- DisableItem(theMenu,kVerifyItem);
-
- CheckItem(theMenu,kShowSignItem,gShowSigners);
- }
-
-
- void DSIGOpenFile(WInfoPtr infoPtr)
- {
- DigSigListPtr dsigList,newDSIG;
- ShapeListPtr shapeList;
-
- dsigList = nil;
-
- for (shapeList=infoPtr->data; shapeList!=nil; shapeList=shapeList->next) {
- if (shapeList->isSigned) {
- newDSIG = NewPtrChk(sizeof(DigSigList));
- if (MemError()!=noErr)
- return;
- newDSIG->shape = shapeList;
- newDSIG->signatureID = shapeList->signatureID;
- newDSIG->inTemp = false;
- newDSIG->shouldDelete = false;
- newDSIG->next = dsigList;
- dsigList = newDSIG;
- shapeList->digSig = newDSIG;
- }
- else
- shapeList->digSig = nil;
- }
-
- infoPtr->otherData[kDSIGData] = dsigList;
- }
-
-
- void DSIGCloseFile(WInfoPtr infoPtr)
- {
- DigSigListPtr dsigList,prevSig;
- short saveResFile;
- Handle resHandle;
-
- saveResFile = CurResFile();
- UseResFile(gDSTempRefNum);
-
- dsigList=infoPtr->otherData[kDSIGData];
- while (dsigList!=nil) {
- if (dsigList->inTemp) {
- SetResLoad(false);
- Get1Resource(kSignatureResType,dsigList->signatureID);
- RmveResource(resHandle);
- SetResLoad(true);
- }
- prevSig = dsigList;
- dsigList = dsigList->next;
- DisposPtrChk(prevSig);
- }
- infoPtr->otherData[kDSIGData] = nil;
-
- UpdateResFile(gDSTempRefNum);
- UseResFile(saveResFile);
- }
-
-
- void DSIGSaveFile(WInfoPtr infoPtr,short newResRef,Boolean saveACopy)
- {
- short saveResFile,oldResRef;
- short newID;
- DigSigListPtr dsigList,oldSig,prevSig;
- Handle resHandle;
-
- oldResRef = infoPtr->resRefNum;
- saveResFile = CurResFile();
-
- prevSig = nil;
- dsigList=infoPtr->otherData[kDSIGData];
- while (dsigList!=nil) {
- if (dsigList->shouldDelete && (dsigList->inTemp || (!saveACopy && (oldResRef==newResRef)))) {
-
- // delete sig resource
-
- if (dsigList->inTemp)
- UseResFile(gDSTempRefNum);
- else
- UseResFile(oldResRef);
- SetResLoad(false);
- resHandle = Get1Resource(kSignatureResType,dsigList->signatureID);
- RmveResource(resHandle);
- SetResLoad(true);
-
- // delete old dsig object from list
-
- if (prevSig)
- prevSig->next = dsigList->next;
- else
- infoPtr->otherData[kDSIGData] = dsigList->next;
-
- oldSig = dsigList;
- dsigList = dsigList->next;
- DisposPtrChk(oldSig);
- }
- else if (dsigList->inTemp || saveACopy) {
-
- // copy sig resource from temp file (or old doc file) to new document file
-
- if (dsigList->inTemp) {
- if (!saveACopy) {
- UseResFile(newResRef);
- newID = Unique1ID(kSignatureResType);
- }
- else
- newID = dsigList->signatureID;
- UseResFile(gDSTempRefNum);
- }
- else {
- newID = dsigList->signatureID; // keep same ID for save a copy saves
- UseResFile(oldResRef);
- }
- resHandle = Get1Resource(kSignatureResType,dsigList->signatureID);
- DetachResource(resHandle);
- UseResFile(newResRef);
- AddResource(resHandle,kSignatureResType,newID,"\p");
- if (ResError()!=noErr) {
- DoError(ResError());
- return;
- }
-
- // re-point objects to new ID
-
- if (saveACopy==false)
- dsigList->inTemp = false;
- dsigList->signatureID = newID;
- dsigList->shape->signatureID = newID;
- }
-
- if (dsigList->shouldDelete==false) {
- prevSig = dsigList;
- dsigList = dsigList->next;
- }
- }
-
- UpdateResFile(gDSTempRefNum);
- if (oldResRef)
- UpdateResFile(oldResRef);
- UpdateResFile(newResRef);
- UseResFile(saveResFile);
- }
-
-
- // needed for add/remove mailer, since this disconnects the data from the document, where
- // the signatures are stored. this function copies all of these signature resources into the
- // temp file when the user does add or remove mailer
-
- void DSIGCopySigsToTemp(WInfoPtr infoPtr)
- {
- DigSigListPtr dsigList;
- short saveResFile,docResFile;
- Handle resHandle;
- short newID;
-
- saveResFile = CurResFile();
- docResFile = infoPtr->resRefNum;
-
- dsigList=infoPtr->otherData[kDSIGData];
- while (dsigList!=nil) {
- if (dsigList->inTemp==false) {
- UseResFile(docResFile);
- resHandle = Get1Resource(kSignatureResType,dsigList->signatureID);
- DetachResource(resHandle);
- UseResFile(gDSTempRefNum);
- newID = Unique1ID(kSignatureResType);
- AddResource(resHandle,kSignatureResType,newID,"\p");
- if (ResError()!=noErr) {
- DoError(ResError());
- return;
- }
- dsigList->signatureID = newID;
- dsigList->shape->signatureID = newID;
- dsigList->inTemp = true;
- }
- dsigList = dsigList->next;
- }
-
- UpdateResFile(gDSTempRefNum);
- UpdateResFile(docResFile);
- UseResFile(saveResFile);
- }
-
-
- void DSIGDrawSigner(ShapeListPtr theShape,Point drawOffset)
- {
- Rect iconRect;
- Pattern pat;
-
- if (!theShape->isSigned)
- return;
-
- if (!gShowSigners)
- return;
-
- SetRect(&iconRect,theShape->anchor.h+drawOffset.h,theShape->anchor.v+drawOffset.v,
- theShape->destination.h+drawOffset.h,theShape->destination.v+drawOffset.v);
- FixRect(&iconRect);
-
- GetIndPattern(pat,sysPatListID,kDSIGPattern);
- PenPat(pat);
- PenSize(kDSIGFrameSize,kDSIGFrameSize);
- FrameRect(&iconRect);
- PenNormal();
-
- iconRect.left = iconRect.right - 16;
- iconRect.top = iconRect.bottom - 16;
- PlotIconID(&iconRect,atNone,ttNone,256);
- }
-
-
- Boolean DSIGHitShape(WindowPtr window,WInfoPtr infoPtr,Point hitPt,Point offsetPos,ShapeListPtr theShape)
- {
- Rect dsigBox;
- Boolean returnVal,hitBox;
- Point mousePt;
- SIGContextPtr sigContext;
- OSErr err;
-
- SetRect(&dsigBox,theShape->anchor.h+offsetPos.h,theShape->anchor.v+offsetPos.v,
- theShape->destination.h+offsetPos.h,theShape->destination.v+offsetPos.v);
- FixRect(&dsigBox);
- dsigBox.left = dsigBox.right-16;
- dsigBox.top = dsigBox.bottom-16;
-
- hitBox = false;
- if (gShowSigners && PtInRect(hitPt,&dsigBox) && theShape->isSigned) {
- while (WaitMouseUp()) {
- GetMouse(&mousePt);
- if (PtInRect(mousePt,&dsigBox)) {
- if (!hitBox) {
- hitBox = true;
- PlotIconID(&dsigBox,atNone,ttNone,257);
- }
- }
- else {
- if (hitBox) {
- hitBox = false;
- PlotIconID(&dsigBox,atNone,ttNone,256);
- }
- }
- }
- PlotIconID(&dsigBox,atNone,ttNone,256);
-
- // verify the selected shape
-
- if (hitBox) {
- err = SIGNewContext(&sigContext);
- if (err==noErr) {
- err = VerifyShape(infoPtr,sigContext,theShape);
- SIGDisposeContext(sigContext);
- }
- if (err!=noErr)
- DoError(err);
- }
-
- returnVal = true;
- }
- else returnVal = false;
- return returnVal;
- }
-
-
- void CommSign(WindowPtr window)
- {
- WInfoPtr infoPtr;
- char hState;
- ShapeListPtr shapeList;
- SIGContextPtr sigContext;
- Size sigSize;
- OSErr err;
-
- if (!IsAppWindow(window))
- return;
-
- err = SIGNewContext(&sigContext);
-
- if (err==noErr) {
-
- infoPtr = BeginWindowAccess(window,&hState);
-
- if (err==noErr)
- err = SIGSignPrepare(sigContext,nil,nil,&sigSize);
-
- for (shapeList=infoPtr->data; (err==noErr) && (shapeList!=nil); shapeList=shapeList->next) {
- if (shapeList->selected)
- err = SignShape(infoPtr,sigContext,shapeList,sigSize);
- InvalShapeArea(window,infoPtr,shapeList);
- }
-
- SIGDisposeContext(sigContext);
- DSIGSetupSignMenu(window,infoPtr);
- EndWindowAccess(window,hState);
- }
-
- if (err!=noErr)
- DoError(err);
- }
-
-
- void CommVerify(WindowPtr window)
- {
- WInfoPtr infoPtr;
- char hState;
- ShapeListPtr shapeList;
- SIGContextPtr sigContext;
- OSErr err;
-
- if (!IsAppWindow(window))
- return;
-
- err = SIGNewContext(&sigContext);
- if (err==noErr) {
-
- infoPtr = BeginWindowAccess(window,&hState);
-
- for (shapeList=infoPtr->data; (err==noErr) && (shapeList!=nil); shapeList=shapeList->next) {
- if (shapeList->selected)
- err = VerifyShape(infoPtr,sigContext,shapeList);
- }
-
- SIGDisposeContext(sigContext);
- EndWindowAccess(window,hState);
- }
-
- if (err!=noErr)
- DoError(err);
- }
-
-
- void CommShowSigners(WindowPtr window)
- {
- WInfoPtr infoPtr;
- char hState;
- ShapeListPtr shapeList;
-
- if (!IsAppWindow(window))
- return;
-
- infoPtr = BeginWindowAccess(window,&hState);
-
- gShowSigners = !gShowSigners;
-
- for (shapeList=infoPtr->data; shapeList!=nil; shapeList=shapeList->next) {
- if (shapeList->isSigned)
- InvalShapeArea(window,infoPtr,shapeList);
- }
-
- DSIGSetupSignMenu(window,infoPtr);
-
- EndWindowAccess(window,hState);
- }
-
-
- /*---------------------------------------------------------------------------------------------*/
-
-
- OSErr SignShape(WInfoPtr infoPtr,SIGContextPtr sigContext,ShapeListPtr theShape,Size sigSize)
- {
- OSErr err;
- Handle signature;
- short resID;
- short saveResFile;
- DigSigListPtr theSig;
-
- // allocate storage for the signature
-
- signature = NewHandleChk(sigSize);
- if (MemError()!=noErr)
- return MemError();
-
- // process the data for the signature
-
- err = ProcessShapeData(sigContext,theShape);
- if (err!=noErr) {
- DisposHandleChk(signature);
- return err;
- }
-
- // create the signature
-
- HLock(signature);
- err = SIGSign(sigContext,(SIGSignaturePtr)*signature,nil);
- HUnlock(signature);
-
- // bail if the sign didn't succeed
-
- if (err!=noErr)
- return err;
-
- // add the signature to the shape
-
- saveResFile = CurResFile();
- UseResFile(gDSTempRefNum);
- resID = Unique1ID(kSignatureResType);
- AddResource(signature,kSignatureResType,resID,"\p");
- if (ResError()==noErr) {
-
- ReleaseResource(signature);
-
- // see if old shape is already signed-- if so, mark the old signature for deletion
-
- if (theShape->isSigned) {
- theSig = theShape->digSig;
- theSig->shouldDelete = true;
- }
-
- // create the signature object and add it to the list, ref to shape
-
- theSig = NewPtrChk(sizeof(DigSigList));
- if (MemError()!=noErr)
- return MemError();
- theSig->shape = theShape;
- theSig->inTemp = true;
- theSig->shouldDelete = false;
- theSig->next = infoPtr->otherData[kDSIGData];
- infoPtr->otherData[kDSIGData] = theSig;
- theSig->signatureID = resID;
-
- theShape->digSig = theSig;
- theShape->signatureID = resID;
- theShape->isSigned = true;
- }
- else {
- DisposHandleChk(signature);
- err = ResError();
- }
- UpdateResFile(gDSTempRefNum);
- UseResFile(saveResFile);
-
- return err;
- }
-
-
- OSErr VerifyShape(WInfoPtr infoPtr,SIGContextPtr sigContext,ShapeListPtr theShape)
- {
- DigSigListPtr theSig;
- short saveResFile;
- Handle sigHandle;
- OSErr err;
- Size signatureSize;
-
- if (theShape->isSigned==false)
- return noErr;
-
- theSig = theShape->digSig;
-
- saveResFile = CurResFile();
- if (theSig->inTemp)
- UseResFile(gDSTempRefNum);
- else
- UseResFile(infoPtr->resRefNum);
- sigHandle = Get1Resource(kSignatureResType,theSig->signatureID);
- err = ResError();
- UseResFile(saveResFile);
- if (err!=noErr)
- return err;
-
- signatureSize = SizeResource(sigHandle);
- HLock(sigHandle);
- err = SIGVerifyPrepare(sigContext,(SIGSignaturePtr)*sigHandle,signatureSize,nil);
- if (err==noErr) {
-
- // process the data for the signature
- err = ProcessShapeData(sigContext,theShape);
- if (err==noErr) {
- err = SIGVerify(sigContext);
- if (err==noErr)
- err = SIGShowSigner(sigContext,nil);
- }
- }
-
- ReleaseResource(sigHandle);
- return err;
- }
-
-
- OSErr ProcessShapeData(SIGContextPtr sigContext,ShapeListPtr theShape)
- {
- OSErr err;
- ShapeListPtr shapeList;
-
- err = noErr;
- if (theShape->shapeType==kBeginGroupTag) {
- for (shapeList=theShape->subList; (shapeList!=nil) && (err==noErr); shapeList=shapeList->next)
- err = ProcessShapeData(sigContext,shapeList);
- }
- else
- err = SIGProcessData(sigContext,theShape,kShapeSignLength);
- return err;
- }